package com.cymal.condition.subject;

import com.cymal.condition.Condition;
import com.cymal.entity.po.answer.Choose;
import com.cymal.entity.po.answer.Completion;
import com.cymal.entity.po.answer.Judge;
import com.cymal.entity.po.subject.AbstractSubject;
import com.cymal.entity.po.subject.CompletionSubject;
import com.cymal.entity.po.subject.JudgeSubject;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;


/**
 * 代码补全题匹配器
 */
@Component
public class CompletionCondition implements Condition<CompletionSubject, Completion> {


    /**
     * Redis模板
     */
    @Autowired
    private RedisTemplate<String, List<Completion>> redisTemplate;


    /**
     * 匹配
     * @param subject 题目.
     * @param requests 请求.
     * @return true or false.
     */
    @Override
    public Boolean matched(CompletionSubject subject, Completion... requests) {
        var key = subject.key();
        List<Completion> chooses = redisTemplate.opsForValue().get(key);
        if (ArrayUtils.isNotEmpty(requests)) {
            Optional<Boolean> result = Arrays.stream(requests)
                    .map(request -> chooses.contains(requests))
                    .filter(BooleanUtils::isFalse)
                    .findFirst();
            return result.orElse(true);
        } else {
            return false;
        }
    }


    /**
     * 匹配.
     * @param subject 题目.
     * @param requests 请求.
     * @return true or false.
     */
    @Override
    public Boolean matched(CompletionSubject subject, Collection<Completion> requests) {
        return matched(subject, requests.toArray(new Completion[requests.size()]));
    }


    /**
     * 返回匹配类型
     * @return 匹配类型
     */
    @Override
    public AbstractSubject.SubjectType conditionType() {
        return AbstractSubject.SubjectType.completion;
    }


}
